/* 작성자 : Jint
 * 작성일 : 140430
 * 내용 : 1:1 서버 채팅 Client
 * 
 * 생성자 
 * 		- 제목 표시줄과 IP 표시창에 자신의 아이피 주소
 * 
 * 각 버튼에 Action Event 추가
 * 입력상자에 Key Event 추가, Enter Key 만 처리
 * 
 * 필요한 필드 추가.
 * 메서드 connect -> 접속버튼클릭 / disconnect -> 접속해제버튼 및 종료버튼시 / msgSend(String) -> 입력창 엔터, 메세지전송버튼클릭 
 * 
 * 	접속
 * 		-해제 버튼 클릭시 각 버튼의 활성 비활성화가 비대칭되도록.
 * 		-서버에 접속중이라는 메세지 dataSet(String)에 전달
 * 		
 * 		
 * 
 */
package network;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;

import java.awt.FlowLayout;

import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.swing.JFormattedTextField;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class SingleChatClient extends JFrame implements Runnable{

	ServerSocket server = null;
	Socket sock = null;
	boolean threadFlag = false;
	StringBuilder data = new StringBuilder();
	BufferedReader receive = null;
	BufferedWriter send = null;
	
	
	private JPanel contentPane;
	private JPanel panel;
	private JPanel panel_1;
	private JLabel lblIp;
	private JButton btnJoin;
	private JButton btnOut;
	private JButton btnMsg;
	private JTextField msgIn;
	private JScrollPane scrollPane;
	private JTextPane result;
	private JFormattedTextField ftfIp;
	private JButton btnChathistory;
	
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					SingleChatClient frame = new SingleChatClient();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	
	
	public SingleChatClient() {
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 693, 512);
		contentPane = new JPanel();
		contentPane.setBackground(Color.PINK);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		contentPane.add(getPanel(), BorderLayout.NORTH);
		contentPane.add(getPanel_1(), BorderLayout.SOUTH);
		contentPane.add(getScrollPane(), BorderLayout.CENTER);
		try{
			InetAddress ia = InetAddress.getLocalHost(); // 주소를 가져와 타이틀을 IP주소로 변경해준다.			
			setTitle("IP Address: " + ia.getHostAddress() + ", Port Number : 4444");
			ftfIp.setText(ia.getHostAddress());
		}catch(Exception ei){
			ei.printStackTrace();
		}
		
	}
	
	@Override
	public void run() {
		/* 서버 소켓을 생성하고
		 * 클라이언트 접속 대기( accept() )
		 *  BufferedWriter 생성
		 *  BufferedReader 생성
		 *  threadFlag = true로 변경
		 *  while(threadFlag){}
		 *  	- 문자열을 수진
		 *  	- 수신된 문자열을 dataSet()메서드에 전달
		 *  입력 스트림들을 닫음
		 *  출력 스트림을 닫음
		 *  서버소켓 닫음	
		 */
		try{			
			String ip = ftfIp.getText();
			sock = new Socket(ip,4444);
			
			
			//if(!sock.isConnected()) sock.close();

			InetAddress ia = sock.getInetAddress();
			dataSet("<b>["+ia.getHostAddress()+"] 서버에 접속하였습니다.</b>");

			OutputStream os = sock.getOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(os);
			send = new BufferedWriter(osw);
			
			InputStream is = sock.getInputStream();
			InputStreamReader isr = new InputStreamReader(is);
			receive = new BufferedReader(isr);
			
			msgSend("입장");	
			
			threadFlag = true;

			while(threadFlag){
				String txRcv = receive.readLine();
				if(txRcv == null){
					threadFlag = false;					
					break;
				}else if(txRcv.equals("Server Down!!!!")){
					threadFlag = false;
				}else if(txRcv.equals("kill!!!!")){
					threadFlag = false;
					msgSend(txRcv);
				}else{
					dataSet("Received Message : "+txRcv);
				}
					
			}

			dataSet("<font size='3' color='#6a5acd'><b>서버와 접속이 끊겼습니다.</b></font>");

			btnJoin.setEnabled(true);
			btnOut.setEnabled(false);			

			receive.close();isr.close();is.close();
			send.close();osw.close();os.close();
			if(sock != null ) sock.close();
			if(server != null) server.close();	

		}catch(Exception ie){
			ie.printStackTrace();
		}
		
	}
	
	public void dataSet(String a){
		data.append(a + "<br/>");
		result.setText(data.toString());
	}
	public void dataSet(String id, String msg){
		data.append(id +" : " + msg + "<br/>");
		result.setText(data.toString());
	}
	public void serverConnect(){
		threadFlag = true;		
		Thread t = new Thread(this); // 여기서는 클래스명.this 라고 안해도 된다. Runnable 이 this로 들어감

		t.start();

		dataSet("<font size='3' color='#6a5acd'><b>채팅이 시작됨</b></font>");			
		btnJoin.setEnabled(false);
		btnOut.setEnabled(true);
		
	}
	
	public void serverDisconnect(){
		threadFlag = false;
		
		btnJoin.setEnabled(true);
		btnOut.setEnabled(false);
		
	}
	
	public void msgSend(String a) throws Exception {
		dataSet("<font color='blue'> 나 : " + a + "</font>");
		send.write(a);
		send.newLine();
		send.flush();
		msgIn.setText("");
		msgIn.requestFocus();
		
	}

	private JButton getBtnJoin() {
		if (btnJoin == null) {
			btnJoin = new JButton("Join");
			btnJoin.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					
						serverConnect();
					
				}
			});
		}
		return btnJoin;
	}
	private JButton getBtnOut() {
		if (btnOut == null) {
			btnOut = new JButton("Out");
			btnOut.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					serverDisconnect();
				}
			});
		}
		return btnOut;
	}
	private JButton getBtnMsg() {
		if (btnMsg == null) {
			btnMsg = new JButton("Message Send");
			btnMsg.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					
					try {
						msgSend(msgIn.getText());						
					} catch (Exception ex) {						
						ex.printStackTrace();
					}
					
				}
			});
		}
		return btnMsg;
	}


	private JPanel getPanel() {
		if (panel == null) {
			panel = new JPanel();
			panel.setBackground(Color.PINK);
			panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
			panel.add(getLblIp());
			panel.add(getFtfIp());
			panel.add(getBtnJoin());
			panel.add(getBtnOut());
		}
		return panel;
	}
	private JPanel getPanel_1() {
		if (panel_1 == null) {
			panel_1 = new JPanel();
			panel_1.setBackground(Color.PINK);
			panel_1.setLayout(new BorderLayout(0, 0));
			panel_1.add(getBtnMsg(), BorderLayout.EAST);
			panel_1.add(getMsgIn(), BorderLayout.CENTER);
			panel_1.add(getBtnChathistory(), BorderLayout.WEST);
		}
		return panel_1;
	}
	private JLabel getLblIp() {
		if (lblIp == null) {
			lblIp = new JLabel("Ip Address");
		}
		return lblIp;
	}
	
	private JTextField getMsgIn() {
		if (msgIn == null) {
			msgIn = new JTextField();
			msgIn.addKeyListener(new KeyAdapter() {
				@Override
				public void keyPressed(KeyEvent k) {
					int a = k.getKeyCode();
					if(a == k.VK_ENTER){
						try {
							msgSend(msgIn.getText());						
						} catch (Exception ex) {						
							ex.printStackTrace();
						}						
					}
				}
			});
			msgIn.setColumns(10);
		}
		return msgIn;
	}
	private JScrollPane getScrollPane() {
		if (scrollPane == null) {
			scrollPane = new JScrollPane();
			scrollPane.setViewportView(getResult());
		}
		return scrollPane;
	}
	private JTextPane getResult() {
		if (result == null) {
			result = new JTextPane();
			result.setContentType("text/html");
		}
		return result;
	}
	private JFormattedTextField getFtfIp() {
		if (ftfIp == null) {
			ftfIp = new JFormattedTextField();
			ftfIp.setColumns(12);
		}
		return ftfIp;
	}
	private JButton getBtnChathistory() {
		if (btnChathistory == null) {
			btnChathistory = new JButton("Chat_History");
			btnChathistory.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					c_history();
					
					
					
				}
			});
		}
		return btnChathistory;
	}
	public void c_history(){
		//DB 용 변수들
		String driver = "oracle.jdbc.driver.OracleDriver";
		String url = "jdbc:oracle:thin:@"+ftfIp.getText()+":1521:xe";
		String db_user = "hr";
		String db_pwd = "hr";
		Connection conn=null;
		try{
			conn=DriverManager.getConnection(url,db_user,db_pwd);	
		}catch(Exception ex){
			ex.printStackTrace();
		}
		
		String sql="select * from chat_history";		
		try{
			PreparedStatement pstmt = conn.prepareStatement(sql);
			ResultSet rs = pstmt.executeQuery();		
			
			while(rs.next()){
				String id = rs.getString("c_id");
				String msg = rs.getString("c_msg");
				dataSet(id, msg);				
			}
			
			
		}catch(Exception ex){
			ex.printStackTrace();
		}		
		
		
		
		
		
		
		
		
		
		
	}
}
